import curses
import item
import unit
import dungeon

class UICurses:
    def __init__(self,game):
        self.stats = game.stats
        self.player = game.player
        self.game = game
        self.keys = game.config['keys']
        self.ncurses = game.config['ncurses']

        self.tabs = {self.keys['character']:'Character',self.keys['inventory']:'Inventory',self.keys['skills']:'Skills'}
        self.moves = [self.keys['up'],self.keys['down'],self.keys['left'],self.keys['right']]
        self.cursors = [self.keys['cursor_up'],self.keys['cursor_down'],self.keys['cursor_left'],self.keys['cursor_right']]
        self.actions = {
            self.keys['up']:self.move,self.keys['down']:self.move,self.keys['left']:self.move,self.keys['right']:self.move,
            self.keys['cursor_up']:self.cursor,self.keys['cursor_down']:self.cursor,
            self.keys['cursor_left']:self.cursor,self.keys['cursor_right']:self.cursor,
            self.keys['character']:self.update_tab,self.keys['inventory']:self.update_tab,self.keys['skills']:self.update_tab,
            self.keys['switch']:self.switch,self.keys['attack']:self.attack,self.keys['skill']:self.skill,
            self.keys['interact']:self.interact,self.keys['describe']:self.describe,self.keys['quit']:self.quit}
        
        self.playing = True
        self.map_selected = True
        self.tab = 'Character'
        self.skill = False
        self.map_cursor = (0,0)
        self.tab_line = 0
        self.num_tab_lines = 0
        self.tab_list = []

        self.scr = curses.initscr()
        curses.savetty()
        curses.noecho()
        curses.cbreak()
        self.scr.keypad(1)

        self.bmap = curses.newwin(int(self.ncurses['map_height'])+2,int(self.ncurses['map_width'])+2,0,0)
        self.bmap.border()
        self.bmap.addstr(0,1,'Dungeon map')
        self.wmap = self.bmap.derwin(int(self.ncurses['map_height']),int(self.ncurses['map_width']),1,1)
        self.bmessage = curses.newwin(int(self.ncurses['message_height'])+2,int(self.ncurses['message_width'])+2,
                                      int(self.ncurses['map_height'])+2,0)
        self.bmessage.border()
        self.bmessage.addstr(0,1,'Messages')
        self.wmessage = self.bmessage.derwin(int(self.ncurses['message_height']),int(self.ncurses['message_width']),1,1)
        self.wmessage.idlok(1)
        self.wmessage.scrollok(1)
        self.btab = curses.newwin(int(self.ncurses['tab_height'])+2,int(self.ncurses['tab_width'])+2,
                                  0,int(self.ncurses['map_width'])+2)
        self.wtab = self.btab.derwin(int(self.ncurses['tab_height']),int(self.ncurses['tab_width']),1,1)
        self.bdescription = curses.newwin(int(self.ncurses['description_height'])+2,int(self.ncurses['description_width'])+2,
                                          int(self.ncurses['tab_height'])+2,int(self.ncurses['map_width'])+2)
        self.bdescription.border()
        self.bdescription.addstr(0,1,'Description')
        self.wdescription = self.bdescription.derwin(int(self.ncurses['description_height']),int(self.ncurses['description_width']),1,1)

        self.update_all()
        self.update_tab(self.keys['character'])
        self.play()

        self.exit()

    def __del__(self):
        '''exit ncurses correctly in case of problem'''
        curses.echo()
        curses.nocbreak()
        self.scr.keypad(0)
        curses.resetty()
        curses.endwin()

    def exit(self):
        '''exit ncurses correctly'''
        curses.echo()
        curses.nocbreak()
        self.scr.keypad(0)
        curses.resetty()
        curses.endwin()

    def play(self):
        '''main loop'''
        while self.playing:
            self.city()
            self.dungeon()

    def city(self):
        '''buy stuff and recuperate'''
        self.update_all()

    def dungeon(self):
        '''play in dungeon'''
        (maxy,maxx) = self.wmap.getmaxyx()
        self.wmap.move(1,1)
        self.update_all()
        while self.playing:
            c = self.scr.getkey()
            if c in self.actions:
                self.actions[c](c)
            self.update_all()

    def move(self,key):
        '''player movement'''
        (y,x) = self.wmap.getyx()
        direction = 'nowhere'
        if key == self.keys['up'] and y > 0:
            y -= 1
            direction = 'up'
        if key == self.keys['down'] and y < 10:
            y += 1
            direction = 'down'
        if key == self.keys['left'] and x > 0:
            x -= 1
            direction = 'left'
        if key == self.keys['right'] and x < 10:
            x += 1
            direction = 'right'
        self.wmap.move(y,x)
        self.update_message('Moved '+direction)

    def cursor(self,key):
        '''cursor movement'''
        if self.map_selected:
            (y,x) = self.map_cursor
            direction = 'nowhere'
            if key == self.keys['cursor_up'] and y > 0:
                y -= 1
                direction = 'up'
            if key == self.keys['cursor_down'] and y < int(self.ncurses['map_height'])-1:
                y += 1
                direction = 'down'
            if key == self.keys['cursor_left'] and x > 0:
                x -= 1
                direction = 'left'
            if key == self.keys['cursor_right'] and x < int(self.ncurses['map_width'])-1:
                x += 1
                direction = 'right'
            self.map_cursor = (y,x)
            self.update_message('Cursored ' + direction + ' in map')
        else:
            y = self.tab_line
            direction = 'nowhere'
            if key == self.keys['cursor_up'] and y > 0:
                y -= 1
                direction = 'up'
            if key == self.keys['cursor_down'] and y < self.num_tab_lines-1:
                y += 1
                direction = 'down'
            self.tab_line = y
            self.update_message('Cursored ' + direction + ' in tab')

    def switch(self,key):
        '''switch between map and tab'''
        self.map_selected = not self.map_selected
        if self.map_selected:
            (y,x) = self.map_cursor
            self.wmap.move(y,x)
            self.update_message('Switched to Map')
        else:
            y = self.tab_line
            self.wtab.chgat(y,0,curses.A_REVERSE)
            self.update_message('Switched to Tab')

    def attack(self,key):
        '''attack at cursor when attack pressed again'''
        self.update_message('Attacking')
        self.update_message('Attacked')

    def skill(self,key):
        '''switch to and from skill-mode'''
        self.skill = not self.skill
        if self.skill:
            self.update_message('Switched to skill')
        else:
            self.update_message('Switched to attack')

    def interact(self,key):
        '''interact at cursor when interact pressed again'''
        self.update_message('Interacting')
        self.update_message('Interacted')

    def describe(self,key):
        '''describe thing at cursor'''
        self.update_description()
        self.update_message('Described')

    def quit(self,key):
        '''quit game'''
        self.playing = False

    def update_all(self):
        '''update all windows'''
        self.scr.refresh()
        self.update_tab()
        self.update_description()
        self.update_message()
        self.update_map()

    def update_map(self):
        '''update map window'''
        self.wmap.clear()
        self.wmap.addstr(0,0,'hp: '+self.player.string('hp'))
        self.wmap.addstr(1,0,'mp: '+self.player.string('mp'))
        if self.map_selected:
            (y,x) = self.map_cursor
            self.wmap.move(y,x)
            curses.curs_set(1)
        self.bmap.refresh()
        self.wmap.refresh()

    def update_tab(self,key=None):
        '''update tab window'''
        if key:
            self.tab = self.tabs[key]
            self.tab_line = 0
            self.btab.clear()
            self.btab.border()
            self.btab.addstr(0,1,self.tab)
            self.btab.refresh()
            self.update_message('Tabbed to ' + self.tab)
        if self.tab == 'Inventory':
            self.wtab.clear()
            self.tab_list = []
            line = 0
            for item in self.player.uitems:
                self.wtab.addstr(line,0,('{:<20} | {:<10} | {:<5}').format(item.iname[:20],item.itype[:10],str(item.iequipped)))
                self.tab_list.append(item)
                line += 1
            self.num_tab_lines = line
        if self.tab == 'Character':
            self.wtab.clear()
            self.wtab.addstr(0,0,('{:<15}:{:^'+str(int(self.ncurses['tab_width'])-16)+'}').format('Name',self.player.uname))
            self.wtab.addstr(1,0,('{:<15}:{:^'+str(int(self.ncurses['tab_width'])-16)+'}').format('Class',self.player.uclass))
            self.wtab.addstr(2,0,('{:<15}:{:^'+str(int(self.ncurses['tab_width'])-16)+'}').format('Level',self.player.ulevel))
            self.wtab.addstr(3,0,('{:<15}:{:^'+str(int(self.ncurses['tab_width'])-16)+'}').format('Experience',self.player.uxp))
            self.wtab.addstr(4,0,('{:<15}:{:^'+str(int(self.ncurses['tab_width'])-16)+'}').format('Health',self.player.string('hp')))
            self.wtab.addstr(5,0,('{:<15}:{:^'+str(int(self.ncurses['tab_width'])-16)+'}').format('Mana',self.player.string('mp')))
            self.wtab.addstr(6,0,('{:<15}:{:^'+str(int(self.ncurses['tab_width'])-16)+'}').format('Strength',self.player.string('str')))
            self.wtab.addstr(7,0,('{:<15}:{:^'+str(int(self.ncurses['tab_width'])-16)+'}').format('Dexterity',self.player.string('dex')))
            self.wtab.addstr(8,0,('{:<15}:{:^'+str(int(self.ncurses['tab_width'])-16)+'}').format('Intelligence',self.player.string('int')))
            self.wtab.addstr(9,0,('{:<15}:{:^'+str(int(self.ncurses['tab_width'])-16)+'}').format('Damage',str(self.player.string('dmg'))))
            self.wtab.addstr(10,0,('{:<15}:{:^'+str(int(self.ncurses['tab_width'])-16)+'}').format('Armor',str(self.player.string('arm'))))
            self.num_tab_lines = 11
        if self.tab == 'Skills':
            self.wtab.clear()
            self.tab_list = []
        if not self.map_selected:
            self.wtab.chgat(self.tab_line,0,-1,curses.A_REVERSE)
            curses.curs_set(0)
        self.wtab.refresh()

    def update_description(self,thing=None):
        '''update description window'''
        self.bdescription.refresh()
        self.wdescription.refresh()

    def update_message(self,message=None):
        '''update message window, or add message and update'''
        if message:
            self.wmessage.scroll()
            self.wmessage.addstr(int(self.ncurses['message_height'])-1,0,message)
        self.bmessage.refresh()
        self.wmessage.refresh()
